package com.ktgj.flight.common.pay;

import action.RsaEnc;
import chinapnr.SecureLink;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.common.base.Strings;
import com.ktgj.common.core.enums.EnumHelper;
import com.ktgj.common.core.utils.helper.StringHelper;
import com.ktgj.flight.common.ruili.drdomain.Chinapnrroot;
import com.ktgj.flight.common.ruili.drdomain.PayRequest;
import com.ktgj.flight.domain.FlightAiraccount;
import com.ktgj.flight.domain.InterfaceEntity.*;
import com.ktgj.flight.service.IFlightAiraccountService;
import javafx.application.Application;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Random;

/**
 * @author
 * @create 2021-10-20 13:18
 */
@Service
public class _HuiFu {


    @Autowired
    private IFlightAiraccountService flightAiraccountService;

    //region 汇付天下航司机票代扣支付信息
    String PayUrl = "https://mas.chinapnr.com/gar/entry.do";
    String CallBack = "127.0.0.1";
    String SingUrl = "http://172.16.5.201:8090/";
    String Mobile = "15210551151";
    String PayUsrId = "bjjinseshiji";
    String AppMerId = "870372";
    String PassWord = "123456"; //"hf84926666";
    String GateId = "61";
    String PgPubk = "hftx/PgPubk.key";
    String MerKeyUrl = "hftx/MerPrK870372.key";
    String OtaBgRetUrl="http://106.38.39.137:8080/flight/callback/drHuiFuCallback";
    /**
     * 航司商户号(航司收款)
     */
    String MerId = "";
    //endregion


    //region 汇付天下航旅出票信息
    String VERSION = "10";
    String REQUTYPE = "Q";
    String CPNROper ="bjjinseshiji";
    String CPNRPSWD = "84926666";
    String PARTNERCODE = "10";
    String KEYVALUE = "123456";
    String IPADDRESS = "airpay.chinapnr.com";
    String IPPORT = "8014";
    String CAllBack="http://106.38.39.137:8080/flight/callback/huifuTicketCallback";
    //endregion

    /**
     * 支付的银行号（我司付款）
     * @param strMerId
     */
    public _HuiFu(String strMerId)
    {
        this.MerId = strMerId;
    }

    public _HuiFu(){ }
    /**
     * 瑞丽航司代理人汇付支付付款
     * @param moRequest
     * @return
     */
    public MoOrderPayResponse _OrderPayment(MoOrderPayRequest moRequest)
    {
        moRequest.OnlyCode = moRequest.OnlyCode;

        MoOrderPayResponse response = new MoOrderPayResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;
        String strRequestData = "";
        String strResponseData = "";
        Date requestTime = new Date();
        Date returnTime = new Date();

        try
        {
            // 验证
            //ExternalNo注解：瑞丽为支付订单号，华夏为订单编码
            if (Strings.isNullOrEmpty(moRequest.OrderID)) {
                response.ErrorMsg = "第三方支付订单号-不能为空";
                response.IsSuccess = false;
                return response;
            }

            if (Strings.isNullOrEmpty(moRequest.PayAmount.toString())) {
                response.ErrorMsg = "支付金额-不能为空";
                response.IsSuccess = false;
                return response;
            }

            if (Strings.isNullOrEmpty(this.MerId)) {
                response.ErrorMsg = "航司商户号-不能为空";
                response.IsSuccess = false;
                return response;
            }

            String Version = "10";
            String CmdId = "Buy";
            String MerId = this.MerId;
            String OrdId = moRequest.OrderID;
            String OrdAmt =moRequest.PayAmount.toString() ;

            String CurCode = "RMB";
            String Pid = moRequest.OrderID;//华夏约定传订单号
            String RetUrl = this.CallBack;
            String MerPriv = moRequest.OrderID;
            String GateId = this.GateId;

            String UsrMp = this.Mobile;
            String CrFlag = "F";
            String PayUsrId = this.PayUsrId;
            String BgRetUrl = "127.0.0.1";
            String EtclientFlag = "Y";
            String EtclientUsrId = PayUsrId;

            String PartnerCode = "10";
            String AppMerId = this.AppMerId;

            PayRequest preq = new PayRequest();
            preq.version = Version;
            preq.cmdId = CmdId;
            preq.merId = MerId;
            preq.ordId = OrdId;
            preq.ordAmt = OrdAmt;
            preq.curCode = CurCode;
            preq.pid = Pid;
            preq.merPriv = MerPriv;
            preq.gateId = GateId;
            preq.usrMp = UsrMp;
            preq.crFlag = CrFlag;
            preq.payUsrId = PayUsrId;
            preq.bgRetUrl = BgRetUrl;
            preq.etclientFlag = EtclientFlag;
            preq.etclientUsrId = EtclientUsrId;
            preq.partnerCode = PartnerCode;
            preq.appMerId = AppMerId;
            preq.retUrl = RetUrl;


            String  ChkValue = this.GetChkValue(preq) ;
            if (ChkValue.indexOf("失败") >= 0) {
                response.ErrorMsg = ChkValue;
                response.IsSuccess = false;
                return response;
            }

            String PayInfo = this.GetPayInfo(preq);
            if (PayInfo.indexOf("失败") >= 0) {
                response.ErrorMsg = PayInfo;
                response.IsSuccess = false;
                return response;
            }

            StringBuilder strSarms = new StringBuilder();
            strSarms.append("Version="+Version);
            strSarms.append("&CmdId="+CmdId);
            strSarms.append("&MerId="+MerId);
            strSarms.append("&OrdId="+OrdId);
            strSarms.append("&OrdAmt="+OrdAmt);
            strSarms.append("&CurCode="+CurCode);
            strSarms.append("&Pid="+Pid);
            strSarms.append("&RetUrl="+RetUrl);
            strSarms.append("&MerPriv="+MerPriv);
            strSarms.append("&GateId="+GateId);
            strSarms.append("&UsrMp="+UsrMp);
            strSarms.append("&CrFlag="+CrFlag);
            strSarms.append("&PayUsrId="+PayUsrId);
            strSarms.append("&BgRetUrl="+BgRetUrl);
            strSarms.append("&OtaBgRetUrl="+OtaBgRetUrl);
            strSarms.append("&EtclientFlag="+EtclientFlag);
            strSarms.append("&EtclientUsrId="+EtclientUsrId);
            strSarms.append("&PayInfo="+PayInfo);
            strSarms.append("&PartnerCode="+PartnerCode);
            strSarms.append("&AppMerId="+AppMerId);
            strSarms.append("&ChkValue="+ChkValue);


            strRequestData = strSarms.toString();

            strResponseData = sendPost(this.PayUrl, strRequestData);
            returnTime = new Date();

            if (Strings.isNullOrEmpty(strResponseData))
            {
                response.ErrorCode = EnumHelper.ReturnCode.请求接口异常.toString();
                response.ErrorMsg = "支付失败，未返回数据";
                response.IsSuccess = false;
                return response;
            }

            XmlMapper xmlMapper = new XmlMapper();

            Chinapnrroot root = xmlMapper.readValue(strResponseData,Chinapnrroot.class);

            if ("000000".equals(root.RespCode)) {
                response.PayInfo.TradeId = root.TrxId;
                response.ErrorCode = EnumHelper.ReturnCode.成功.toString();
                response.ErrorMsg = "支付成功";
                response.IsSuccess = true;
            }
            else {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = root.ErrorMsg;
                response.IsSuccess = false;
                return response;
            }
        }
        catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            ex.printStackTrace();
            return response;
        }
        return response;
    }

    /**
     * 航信B2B汇付自动出票
     * @param request
     * @return
     */
    public MoAutoPayOutTickeResponse _AutoPayOutTicket(MoAutoPayOutTicketRequest request)
    {

        String uuId = request.OrderID;
//        int uuId = new Random().nextInt(10000) % (10000 - 1000 + 1) + 1000;

        //读取系统中B2B对应的航司账户和密码
        FlightAiraccount flightAiraccount = flightAiraccountService.selectFlightAirAccountByAirlinerId(request.AirCode);

        String B2BUser = "";
        String B2BPass = "";

        if (flightAiraccount != null)
        {
            B2BUser = flightAiraccount.getLoginid().trim();
            B2BPass = flightAiraccount.getPassword().trim();
        }


        String payPwd = DigestUtils.md5Hex(KEYVALUE).toUpperCase(); //支付密码(转大写)

        String strSign = KEYVALUE + VERSION + REQUTYPE + request.BigPnr + uuId + request.AirCode + request.TicketAmount + B2BUser + B2BPass + "2" + CPNROper + payPwd + CAllBack + PARTNERCODE;


        String ChkValue = DigestUtils.md5Hex(strSign).toUpperCase();


        String requestInfo = String.format("VERSION=%s&REQTYPE=%s&PNRNO=%s&AIRLINES=%s&USERNAME=%s&B2BPSWD=%s&PARTNERCODE=%s&RETURL=%s&GUID=%s&FACEVALUE=%s&PAYTYPE=%s&CPNROPER=%s&CPNRPSWD=%s&CHKVALUE=%s&",
                VERSION, REQUTYPE, request.BigPnr, request.AirCode, B2BUser, B2BPass, PARTNERCODE, CAllBack, uuId, request.TicketAmount.toString(), "2", CPNROper, payPwd, ChkValue);

        MoAutoPayOutTickeResponse autoPayOutTickeResponse = new MoAutoPayOutTickeResponse();

        String str = "0" + (requestInfo.length()) + requestInfo;

        StringBuilder builder = null;
        try
        {
            Socket clientSocket = new Socket(IPADDRESS, Integer.valueOf(IPPORT));
            PrintWriter printWriter = new PrintWriter(clientSocket.getOutputStream());
            printWriter.write(str);
            printWriter.flush();
            InputStream is = clientSocket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "GBK");
            BufferedReader br = new BufferedReader(isr);
            String info = null;
            builder = new StringBuilder();
            while ((info = br.readLine()) != null)
            {
                builder.append(info);
            }
            br.close();
            is.close();
            clientSocket.close();
            if (builder.toString().equals("0011QUERY_VALID"))
            {
                autoPayOutTickeResponse.IsSuccess = true;
                autoPayOutTickeResponse.statusMsg = "汇付天下出票操作成功！";
                autoPayOutTickeResponse.OrderID = request.OrderID;
            }else
            {
                autoPayOutTickeResponse.IsSuccess = false;
                autoPayOutTickeResponse.ErrorMsg = "汇付天下出票操作失败！";
                autoPayOutTickeResponse.OrderID = request.OrderID;
            }
        } catch (IOException e)
        {
            autoPayOutTickeResponse.ErrorMsg = "汇付天下出票操作失败！";
        }
        return autoPayOutTickeResponse;
    }
    public OutTicketCheckResponse checkOutTicket(MoAutoPayOutTicketRequest moRequest)
    {
        OutTicketCheckResponse response = new OutTicketCheckResponse();
        if (StringHelper.isNullOrEmpty(moRequest.OrderID))
        {
            response.setSuccess(false);
            response.setMsg("商户订单号-不能为空");
            return response;
        }
        if (StringHelper.isNullOrEmpty(moRequest.PayAmount.toString()))
        {
            response.setMsg("支付金额-不能为空");
            response.setSuccess(false);
            return response;
        }
        if (StringHelper.isNullOrEmpty(moRequest.AirCode))
        {
            response.setMsg("航司号-不能为空");
            response.setSuccess(false);
            return response;
        }
        response.setSuccess(true);
        response.setMsg("校验出票参数成功！");
        return response;
    }

    /**
     * GetChkValue加签
     * @param
     * @return
     */
    private String GetChkValue(PayRequest dto){
        String filePath = this.getClass().getClassLoader().getResource(MerKeyUrl).getPath();
        String signChkValue = dto.version + dto.cmdId + dto.merId + dto.ordId + dto.ordAmt + dto.curCode + dto.pid +
                dto.retUrl + dto.merPriv + dto.gateId + dto.usrMp + dto.crFlag + dto.payUsrId + dto.bgRetUrl + dto.appMerId;

        SecureLink sk = new SecureLink();
        int flag = sk.SignMsg(dto.appMerId, filePath, signChkValue);
        if (flag == 0) {
            return sk.getChkValue();
        }
        return "ChkValue加签失败:" + flag;
    }

    /**
     * PayInfo
     * @param dto
     * @return
     */
    public String GetPayInfo(PayRequest dto){
        String pg = this.getClass().getClassLoader().getResource("hftx/PgPubk.key").getPath();
        RsaEnc rsa = new RsaEnc();
        int flag = rsa.rsaEncrypt(dto.merId, dto.ordId, dto.ordAmt, dto.payUsrId, this.PassWord, pg);
        if (flag == 0) {
            return rsa.getRasStr();
        }
        return "PayInfo加密失败:" + flag;

    }

    /**
     * 发送请求
     * @param url
     * @param param
     * @return
     */
    public static String sendPost(String url, String param) {
        String result = "";
        try {
            URL httpurl = new URL(url);
            HttpURLConnection httpConn = (HttpURLConnection) httpurl.openConnection();
            httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            httpConn.setDoOutput(true);
            httpConn.setDoInput(true);
            PrintWriter out = new PrintWriter(new OutputStreamWriter(httpConn.getOutputStream(), StandardCharsets.UTF_8));
            out.print(param);
            out.flush();
            out.close();
            BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "gbk"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            in.close();
        } catch (Exception e) {
            System.out.println(e);
        }
        return result;
    }


}
